/*
 * Copyright 2017 wshunli
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.basemap.GZtianditu;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;

import com.basemap.api.BaseMapApi;
import com.basemap.api.MapApi;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.FutureTarget;
import com.esri.arcgisruntime.arcgisservices.TileInfo;
import com.esri.arcgisruntime.data.TileKey;
import com.esri.arcgisruntime.geometry.Envelope;
import com.esri.arcgisruntime.layers.ImageTiledLayer;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutionException;

public class GZTianDiTuLayer extends ImageTiledLayer {

    private static final String TAG = "TianDiTuLayer";

    private int layerType = 0;
    private String cachePath = null;
    private GZTianDiTuLayerInfo layerInfo;
    private String token = null;
    private String type = null;
    private Context context = null;

    public GZTianDiTuLayer(TileInfo tileInfo, Envelope fullExtent) {
        super(tileInfo, fullExtent);
    }

    @Override
    protected byte[] getTile(TileKey tileKey) {

        if (this.getToken() == null) {
//            Log.e(TAG, "Please set the token value. See http://lbs.tianditu.gov.cn/authorization/authorization.html");
        }
        int level = tileKey.getLevel();
        int col = tileKey.getColumn();
        int row = tileKey.getRow();
        if (level > layerInfo.getMaxZoomLevel()
                || level < layerInfo.getMinZoomLevel())
            return new byte[0];

        byte[] bytes = null;
        if (cachePath != null) {
//            //100万（8级以下） 的删除
//            if (type.equals("fwx") && level<9) {
//                String dir = cachePath + "/" + level + "/";
//                if (new File(dir).exists()) {
//                    for (File file : new File(dir).listFiles()) {
//                        if (file.exists()) {
//                            file.delete();
//                        }
//                    }
//                    new File(dir).delete();
//                }
//            }
//
            if (!new File(cachePath).exists()) new File(cachePath).mkdir();
            bytes = getOfflineCacheFile(cachePath, level, col, row);
        }
        if (bytes == null) {
            String url = null;
            //贵州天地图
            String key = "b1b55f2720244fd6b6c2ba46a3f3a6be";
            if (MapApi.gzTdtTK != null) {
                key = MapApi.gzTdtTK;
            }
            url = layerInfo.getUrl()
                    + "?key=" + key + "&service=wmts&request=gettile&version=1.0.0&style=default&layer="
                    + layerInfo.getLayerName() + "&format=tiles&tilematrixset="
                    + layerInfo.getTileMatrixSet() + "&tilecol=" + col
                    + "&tilerow=" + row + "&tilematrix=" + (level);

            FutureTarget<File> submit = null;
            submit = Glide.with(context)
                    .asFile()
                    .load(url)
                    .error((Drawable) null)
                    .submit();
            try {
                try {
                    File file = submit.get();
                    FileInputStream inputStream = new FileInputStream(file);
                    bytes = getBytes(inputStream);
                    if (cachePath != null) {
                        AddOfflineCacheFile(cachePath, level, col, row, bytes, type);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }


        }
        return bytes;
    }


    // 保存切片到本地
    private void AddOfflineCacheFile(String cachePath, int level, int col, int row, byte[] bytes, String type) {
        File file = new File(cachePath);
        if (!file.exists()) file.mkdirs();
        File levelFile = new File(cachePath + "/" + level);
        if (!levelFile.exists()) levelFile.mkdirs();
        File rowFile = new File(new StringBuilder().append(cachePath).append("/").append(level).append("/").append(row).append("x").append(col).append(".tdt").toString());

        if (!rowFile.exists() && bytes != null) {
            Bitmap mBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);// bitmap

            BufferedOutputStream bos = null;
            try {
                bos = new BufferedOutputStream(new FileOutputStream(rowFile));
                mBitmap.compress(Bitmap.CompressFormat.PNG, 80, bos);
                bos.flush();
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    // 从本地获取切片
    private byte[] getOfflineCacheFile(String cachePath, int level, int col, int row) {
        byte[] bytes = null;
        File rowFile = new File(cachePath + "/" + level + "/" + row + "x" + col + ".tdt");
        if (rowFile.exists()) {
            try {
                FileInputStream in = new FileInputStream(rowFile);
                bytes = getBytes(in);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bytes;
    }

    // 读取字节数组
    private byte[] getBytes(InputStream is) throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
        byte[] temp = new byte[1024];
        int size;
        while ((size = is.read(temp)) != -1) {
            out.write(temp, 0, size);
        }
        is.close();
        out.flush();
        return out.toByteArray();
    }

    public int getLayerType() {
        return layerType;
    }

    public void setLayerType(int layerType) {
        this.layerType = layerType;
        this.layerInfo = GZLayerInfoFactory.getLayerInfo(layerType);
    }

    public String getCachePath() {
        return cachePath;
    }

    public void setCachePath(String cachePath) {
        this.cachePath = cachePath == null ? null : cachePath + layerInfo.getLayerName() + "_" + layerInfo.getTileMatrixSet();
    }

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public void setContext(Context context) {
        this.context = context;
    }
}
